-- 战斗Entity头上血条(状态)栏
local MClass = require("app.battleV3.ui.MClass")

local PlayerStatusBar = MClass("PlayerStatusBar")
local Buff = require("app.battleV3.ui.objs.Buff")
local NodePool = custom.NodePool:getInstance()

local CCNode_setPosition = cc.Node.setPosition

local TeamName_Color = cc.c4b(189,255,0, 255)
local EnemyName_Color = cc.c4b(255,1,1, 255)

local Enum_BattleActorType_self = Enums.BattleActorType.self
local Enum_BattleActorType_teammate = Enums.BattleActorType.teammate
local Enum_BattleActorType_enemy = Enums.BattleActorType.enemy
local POSYOFFSET = 50
local POSYOFFSET_2 = 25
local POSYINIT = -2000

local specialHPPanelWidth = 183 -- 特殊血条 panel宽

function PlayerStatusBar.create()
    local ret = NodePool:getByKey("PlayerStatusBar")
    if not ret then
        ret = cc.CSLoader:createNode(Res.NewBattleStatusBar,false,true)
    else
        --print("PlayerStatusBar:create ",NodePool:size("PlayerStatusBar"))
    end
    return PlayerStatusBar.new(ret)
end

function PlayerStatusBar:free()
    if not cc.isDead(self.root) then
        self.root:setPositionY(POSYINIT)
        self.root:removeFromParent(false)
        NodePool:put(self.root,"PlayerStatusBar")
    end
end

--ctor 初始化UI init设置静态数据 setData设置动态数据
function PlayerStatusBar:ctor()
    --self.root 默认为根节点
    self.panel = self:findChild("Panel")
    self.name = self.panel:findChild("name")
    self.flag = self.panel:findChild("selected_flag")

    self.hpTotal = self.panel:findChild("group_xuetiao")
    self._hpVisibleFlag = true
    self.hpBar1 = self.panel:findChild("group_xuetiao/bar_foe/bar")
    self.hpBar1Bg = self.panel:findChild("group_xuetiao/bar_foe")

    self.hpBar2 = self.panel:findChild("group_xuetiao/bar_team/bar")
    self.hpBar2Bg = self.panel:findChild("group_xuetiao/bar_team")

    self.specialHPSign = self.panel:findChild("group_xuetiao/Panel")
    specialHPPanelWidth = self.specialHPSign:getContentSize2()

    self.starPanel = self.panel:findChild("Panel_star")

    self.soulPanel = self.panel:findChild("soul")
    self.soulCountLabel = self.panel:findChild("soul/num")
    self.soulEffectAni = self.panel:findChild("num")

    self:initVisibleCtrl()

    self.isSelected = false
    self.bFlag = false
    self.showCoreBuff = false
    -- self.isForceShowStatus = false --强制显示状态条

     --Stars
    self.stars = {}
    for i=1,5 do
        local star = {}
        local bgStr = "Panel_star/bg_"..i
        local starStr = "Panel_star/s_"..i
        star.bg = self.panel:findChild(bgStr)
        star.star = self.panel:findChild(starStr)
        self.stars[i] = star
    end

    --时间怪
    self.timeMonsterIcon = self.panel:findChild("group_xuetiao/icon_time")
    assert(self.timeMonsterIcon)
    --核心buff
    self.buffPanel = Buff.new(self.panel:findChild("buff"))
    self.iconAuto = self.panel:findChild("group_xuetiao/icon_auto")

	self:init()

    -- 新手战不显示
    if not app:isBattleGuideComp() then
        self:setVisible(true)
        self.hpTotal:setVisible(false)
        self.starPanel:setVisible(false)
        self.flag:setVisible(false)
        self.name:setVisible(false)
        self.buffPanel:setVisible(false)
        self.soulPanel:setVisible(false)
    end
end

function PlayerStatusBar:initVisibleCtrl()
    self.visibleCtrl = {}
    --这个数组需要初始化下，才能保证其在 pairs 中的排序是以 下标从小到大的顺序遍历
    --必须要先赋值，直接设置为nil的话，后面遍历的时候也不是按顺序的
    for _, idx in pairs(Enums.BattleStatusBarVisibleCtrlPriority) do
        self.visibleCtrl[idx] = true
    end
    --初始化设置为nil
    for idx, _ in pairs(self.visibleCtrl) do
        self.visibleCtrl[idx] = nil
    end
end

function PlayerStatusBar:init()
    self.bAutoBattle = UD.setting:getIsAutoBattle()

    -- 只有设置为可见，才能通过作为Actor的attachment更新位置
    self:setVisible(false)
    self.root:setPositionY(POSYINIT)

    self.flag:setVisible(false)
	self.hpBar2:setVisible(false)
	self.hpBar2Bg:setVisible(false)

	self.hpBar = self.hpBar1
    self.hpBarBg = self.hpBar1Bg

    self.timeMonsterIcon:setVisible(false)
    self.soulPanel:setVisible(false)
    self.soulEffectAni:setVisible(false)

	for i = 1, Constant.BattleComboPointMax do
		local star = self.stars[i]
		star.bg:setVisible(false)
		star.star:setVisible(false)
	end

    local handler = EM:on("onSettingShowBattlePalHp", function(name, isShow)
        self:setHpBySetting(isShow, UD.setting:isShowBattleFoeHp())
    end)
    BattleUIEvent:addEmHandle(handler)
    handler = EM:on("onSettingShowBattlePalName", function(name, isShow)
        self:setNameBySetting(isShow, UD.setting:isShowBattleFoeName())
    end)
    BattleUIEvent:addEmHandle(handler)
    handler = EM:on("onSettingShowBattleFoeHp", function(name, isShow)
        self:setHpBySetting( UD.setting:isShowBattlePalHp(), isShow)
    end)
    BattleUIEvent:addEmHandle(handler)
    handler = EM:on("onSettingShowBattleFoeName", function(name, isShow)
        self:setNameBySetting(UD.setting:isShowBattlePalName(), isShow)
    end)
    BattleUIEvent:addEmHandle(handler)
    handler = EM:on("onSettinAutoBattle", function(name, isShow)
        self.bAutoBattle = isShow
    end)
    BattleUIEvent:addEmHandle(handler)
end

-- 开启特殊血条
function PlayerStatusBar:setSpecialHPMax(specialHPMax)
    if self._specialHPInitEnd then
        return
    end
    local isSpecialHPFlag = 0 < specialHPMax or false
    self.specialHPSign:setVisible(isSpecialHPFlag)
    if isSpecialHPFlag then
        local shownNum = 0
        local nodeListTemp = {}
        for i = 1, Constant.BattleSpecialHPNodeMaxNum do
            local ndoeTemp = self.specialHPSign:getChildByName("Image_" .. i)
            table.insert(nodeListTemp, ndoeTemp)

            if i < specialHPMax then
                shownNum = shownNum + 1
                ndoeTemp:setVisible(true)
            else
                ndoeTemp:setVisible(false)
            end
        end
        local distanceX = specialHPPanelWidth/(shownNum + 1)
        for i, v in ipairs(nodeListTemp) do
            local posX = 0 + distanceX * i
            v:setPositionX(posX)
        end
    end
    self._specialHPInitEnd = true
end

-- 开启核心buff
function PlayerStatusBar:showBuff(bShow, buffData)
    self.initPosY = self.initPosY or self.panel:getPositionY()
    self.buffInitPosY = self.buffInitPosY or self.buffPanel:getPositionY()
    self.showCoreBuff = bShow --此处记录一下是否显示核心buff
    if bShow then
        self.buffPanel:setVisible(true)
        if self.starPanel:isVisible() then
            self.panel:setPositionY(self.initPosY+POSYOFFSET + POSYOFFSET_2)
            self.buffPanel:setPositionY(self.buffInitPosY - POSYOFFSET_2)
        else
            self.panel:setPositionY(self.initPosY+POSYOFFSET)
        end

        if buffData then
            self:updateBuff(buffData)
        end
    else
        self.buffPanel:setVisible(false)
        self.buffPanel:setPositionY(self.buffInitPosY)
        self.panel:setPositionY(self.initPosY)
    end
end

-- 更新核心buff
function PlayerStatusBar:updateBuff(data)
    self.buffPanel:setData(data)
end

-- 设置是否开启显示/隐藏控制
function PlayerStatusBar:setCtrlVisible(index, b)
    if b then
        if index == Enums.BattleStatusBarVisibleCtrlPriority.PVP then
            --控制显示
            self.visibleCtrl[index] = true
        else
            --控制隐藏
            self.visibleCtrl[index] = false
        end
    else
        --移除控制
        self.visibleCtrl[index] = nil
    end
    self:refreshVisible()
end

function PlayerStatusBar:refreshVisible()
    self:setVisible(true)
    -- 新手战不显示
    if not app:isBattleGuideComp() then
        self.hpTotal:setVisible(false)
        self.starPanel:setVisible(false)
        self.flag:setVisible(false)
        self.name:setVisible(false)
        self.buffPanel:setVisible(false)
        self.soulPanel:setVisible(false)
        self.soulEffectAni:setVisible(false)
        return
    end

    --类型
    local actorType = self.actorType
    if actorType ~= Enum_BattleActorType_self  and actorType ~= Enum_BattleActorType_teammate then
        self.flag:setVisible(self.bFlag)
    else
        self.flag:setVisible(false)
    end

    -- 获取最上层的控制去刷新显示还是隐藏血条
    local visibleCtrlCount = 0
    for idx, visible in pairs(self.visibleCtrl) do
--        print("visibleCtrl idx:", idx, visible)
        visibleCtrlCount = visibleCtrlCount + 1
        if actorType == Enum_BattleActorType_self then
            self.starPanel:setVisible(visible)
        else
            self.starPanel:setVisible(false)
        end
        if actorType ~= Enum_BattleActorType_self then
            if visible then
                self.buffPanel:setVisible(self.showCoreBuff)
            else
                self.buffPanel:setVisible(false)
            end
        end
        self.name:setVisible(visible)
        self.hpTotal:setVisible(visible)
        if self.flagSoul then
            self.soulPanel:setVisible(visible)
        end

        break
    end

    if visibleCtrlCount > 0 then
        return
    else
        if actorType == Enum_BattleActorType_self then
            self.starPanel:setVisible(true)
        end
        if actorType ~= Enum_BattleActorType_self then
            self.buffPanel:setVisible(self.showCoreBuff)
        end
        self.name:setVisible(true)
        self.hpTotal:setVisible(true)
        if self.flagSoul then
            self.soulPanel:setVisible(true)
        end
    end

    if actorType ~= Enum_BattleActorType_self  then
        self:setHpBySetting(UD.setting:isShowBattlePalHp(), UD.setting:isShowBattleFoeHp())
        self:setNameBySetting(UD.setting:isShowBattlePalName(), UD.setting:isShowBattleFoeName())
    end

    --是否被选中
    if self.isSelected and actorType ~= Enum_BattleActorType_self then
        self.name:setVisible(true)
        self.hpTotal:setVisible(true)
    end
end

function PlayerStatusBar:resetVisibleAfterRevive()
    self.name:setVisible(true)
    self.hpTotal:setVisible(true)
end

function PlayerStatusBar:setHpBySetting(flagShowPal, flagShowFoe)
    local actorType = self.actorType
    if actorType == Enum_BattleActorType_teammate then
        self.hpTotal:setVisible(flagShowPal)
    elseif actorType == Enum_BattleActorType_enemy then
        self.hpTotal:setVisible(flagShowFoe)
    end
end

function PlayerStatusBar:setNameBySetting(flagShowPal, flagShowFoe)
    local actorType = self.actorType
    if actorType == Enum_BattleActorType_teammate then
        self.name:setVisible(flagShowPal)
    elseif actorType == Enum_BattleActorType_enemy then
        self.name:setVisible(flagShowFoe)
    end
end

function PlayerStatusBar:setFlag(bFlag)
    self.bFlag = bFlag
end

function PlayerStatusBar:setEnemy(actorType)
    if self.actorType==actorType then
        return
    end

    self.actorType = actorType

    if actorType == Enum_BattleActorType_self then
        self:refreshVisible()
        self.hpBar1:setVisible(false)
        self.hpBar1Bg:setVisible(false)
        self.hpBar2:setVisible(true)
        self.hpBar2Bg:setVisible(true)

        self.hpBar = self.hpBar2
        self.hpBarBg = self.hpBar2Bg
        self.name:setTextColor(TeamName_Color)
        self.iconAuto:setVisible(self.bAutoBattle)
    elseif  actorType == Enum_BattleActorType_teammate then
        self.hpBar1:setVisible(false)
        self.hpBar1Bg:setVisible(false)
        self.hpBar2:setVisible(true)
        self.hpBar2Bg:setVisible(true)
        self.name:setVisible(true)
        self.hpBar = self.hpBar2
        self.hpBarBg = self.hpBar1Bg
        self.name:setTextColor(TeamName_Color)
    else
        self.hpBar1:setVisible(true)
        self.hpBar1Bg:setVisible(true)
        self.hpBar2:setVisible(false)
        self.hpBar2Bg:setVisible(false)

        self.hpBar = self.hpBar1
        self.name:setTextColor(EnemyName_Color)
    end

    if self.per then
        self:setPercent(self.per)
    end

    self:setHpBySetting(UD.setting:isShowBattlePalHp(), UD.setting:isShowBattleFoeHp())
    self:setNameBySetting(UD.setting:isShowBattlePalName(), UD.setting:isShowBattleFoeName())

    -- 新手战不需要显示
    if not app:isBattleGuideComp() then
        self:setVisible(true)
        self.hpTotal:setVisible(false)
        self.starPanel:setVisible(false)
        self.flag:setVisible(false)
        self.name:setVisible(false)
        self.buffPanel:setVisible(false)
        self.soulPanel:setVisible(false)
        self.soulEffectAni:setVisible(false)
    end
end

function PlayerStatusBar:setIsTimeMonster(b)
    self.timeMonsterIcon:setVisible(b)
end

-- 开启灵魂强度
function PlayerStatusBar:setSoulCount(num)
    self.flagSoul = true
    self.soulPanel:setVisible(true)
    self.soulCountLabel:setString(tostring(num))
end

function PlayerStatusBar:playSoulGetEffect(num)
    local soulEffectAction = cc.CSLoader:createTimeline(Res.AniMobaSoulEffect)
    soulEffectAction:play("in", false)
    self.soulEffectAni:findChild("Panel/num"):setString(tostring(num))
    self.soulEffectAni:setVisible(true)
    self.soulEffectAni:runAction(soulEffectAction)
    scheduler.newCron(function()
        if cc.isAlive(self.soulEffectAni) then
            self.soulEffectAni:setVisible(false)
        end
    end, Constant.BattleMobaSoulEffectLastTime)
end

function PlayerStatusBar:playSoulLoseEffect(num)
    local soulEffectAction = cc.CSLoader:createTimeline(Res.AniMobaSoulEffect)
    soulEffectAction:play("out", false)
    self.soulEffectAni:findChild("Panel/num"):setString(tostring(num))
    self.soulEffectAni:setVisible(true)
    self.soulEffectAni:runAction(soulEffectAction)
    scheduler.newCron(function()
        if cc.isAlive(self.soulEffectAni) then
            self.soulEffectAni:setVisible(false)
        end
    end, Constant.BattleMobaSoulEffectLastTime)
end

function PlayerStatusBar:setData(data)

end

function PlayerStatusBar:updateData(data)

end

function PlayerStatusBar:setStar(num, max, bDead)
    if self.actorType == Enum_BattleActorType_self and not bDead then
        for i = 1, max do
            local star = self.stars[i]
            local bShine = num>=i and true or false
            star.bg:setVisible(true)
            star.star:setVisible(bShine)
        end
    end
end

function PlayerStatusBar:setName(str)
	self.name:setString(str)
end

function PlayerStatusBar:setPercent(per)
    self.per = per
	self.hpBar:setPercent(per)

    if per<=0 then
        self.buffPanel:setVisible(false)
    end

    if self.actorType == Enum_BattleActorType_self then
        self.iconAuto:setVisible(self.bAutoBattle)
    end
end

function PlayerStatusBar:bindSkillEventNode(skillEventNode)
    self.skillEventNode = skillEventNode
end

function PlayerStatusBar:setSelect(bSel)
    local actorType = self.actorType
	if actorType ~= Enum_BattleActorType_self then
        self.isSelected = bSel
        self:refreshVisible()
    end

    local skillEventNode = self.skillEventNode
    if  skillEventNode and skillEventNode:isShow() then
        local x,y = self:getPosition()
        if self.hpTotal:isVisible() or self.name:isVisible() then
            CCNode_setPosition(skillEventNode.root,x,y+40)
        else
            CCNode_setPosition(skillEventNode.root,x,y)
        end
    end
end

function PlayerStatusBar:updateSkillEventNodePosition()
    local skillEventNode = self.skillEventNode
    if skillEventNode and skillEventNode:isShow() then
        local x,y = self:getPosition()
        if self.hpTotal:isVisible() or self.name:isVisible() then
            CCNode_setPosition(skillEventNode.root, x, y + 40)
        else
            CCNode_setPosition(skillEventNode.root, x, y)
        end
    end
end

-- 隐藏血条显示
function PlayerStatusBar:shouldHideAllHpUI( b )
    if self._hpVisibleFlag == b then return end
    self._hpVisibleFlag = b

    -- 隐藏血条时特效的显示
    if cc.isDead( self.hpHideEffectNode ) then
        local params = {
            path = Res.HideHpEffect_2.dir,
            armatureName = Res.HideHpEffect_2.name,
            animationName = "",
            skeletonName = Res.HideHpEffect_2.name
        }
        local Armature = app:getClass("Armature")
        self.hpHideEffectNode = Armature.create( params )
        self.hpBar:getParent():addChild( self.hpHideEffectNode )
        self.hpHideEffectNode:setPosition( self.hpBar:getPosition() )
        self.hpHideEffectNode:setScale( 0.7 )
    end
    self.hpHideEffectNode:setVisible( b )
    if b then
        self.hpHideEffectNode:play( "effcreat", 1, function()
            self.hpHideEffectNode:play( "effloop", 1, function()
                self.hpHideEffectNode:play( "effdead", 1 )
            end )
        end )
    end
end

function PlayerStatusBar:clearHideEffect()
    if not cc.isDead(self.hpHideEffectNode) then
        self.hpHideEffectNode:removeFromParent()
        self.hpHideEffectNode = nil
    end
end

return PlayerStatusBar
